package pl.grabar.clinic.core.dao.db;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;

import pl.grabar.clinic.core.dao.Dao;
import pl.grabar.clinic.core.dao.EntityManagerFactoryService;
import pl.grabar.clinic.core.domain.person.Patient;
import pl.grabar.clinic.core.domain.visit.Visit;

public class VisitDataBaseDao implements Dao<Visit> {

	private static final Log LOG = LogFactory.getLog(VisitDataBaseDao.class);

	@Autowired
	private EntityManagerFactoryService entityManagerFactory;

	private EntityManager entityManager;

	public void init() {
		this.entityManager = entityManagerFactory.getEntityManag();
	}

	@Override
	public Visit findById(Serializable id) throws SQLException {
		Visit visit= null;
		try {
			entityManager.getTransaction().begin();
			visit = entityManager.find(Visit.class, Long.parseLong((String) id));
			entityManager.getTransaction().commit();
		} catch (Exception e) {
			entityManager.getTransaction().rollback();
			e.printStackTrace();
			LOG.info(e.getMessage());
			LOG.debug("DEBUG: ", e);
		}
		return visit;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Visit> findAll() throws SQLException {
		List<Visit> listVisit = new ArrayList<>();
		try {
			entityManager.getTransaction().begin();
			Query query = entityManager.createQuery("select k from Visit k");
			listVisit = (ArrayList<Visit>) query.getResultList();
			entityManager.getTransaction().commit();
		} catch (Exception e) {
			entityManager.getTransaction().rollback();
			e.printStackTrace();
			LOG.info(e.getMessage());
			LOG.debug("DEBUG: ", e);
		}
		return listVisit;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Visit> findAll(Integer pageNumber, Integer pageSize, String sortProperty, String sortOrder) throws SQLException {
		List<Visit> listVisit = new ArrayList<>();
		try {
			entityManager.getTransaction().begin();
			Query query = entityManager.createQuery("select k from Visit k where k.isActive = true");
			listVisit = (ArrayList<Visit>) query.getResultList();
			entityManager.getTransaction().commit();
		} catch (Exception e) {
			entityManager.getTransaction().rollback();
			e.printStackTrace();
			LOG.info(e.getMessage());
			LOG.debug("DEBUG: ", e);
		}
		return listVisit;
	}

	@Override
	public List<Visit> findAll(Integer pageNumber, Integer pageSize, String sortProperty, String sortOrder, Map<String, String> filter) throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Long countAll() throws SQLException {
		Long cResults = 0l;
		try {
			entityManager.getTransaction().begin();
			Query query=entityManager.createQuery("SELECT COUNT(*) FROM Visit p");
			cResults=(Long) query.getSingleResult();
			entityManager.getTransaction().commit();
		} catch (Exception e) {
			entityManager.getTransaction().rollback();
			LOG.info(e.getMessage());
			LOG.debug("DEBUG: ", e);
		}	
		return cResults;
	}

	@Override
	public Long countAll(Map<String, String> filter) throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void save(Visit objectToSave) throws SQLException {
		try {
			entityManager.getTransaction().begin();
			entityManager.persist(objectToSave);
			entityManager.getTransaction().commit();
		} catch (Exception e) {
			entityManager.getTransaction().rollback();
			LOG.info(e.getMessage());
			LOG.debug("DEBUG: ", e);
		}		
	}

	@Override
	public void update(Visit transientObject) throws SQLException {
		try {
			entityManager.getTransaction().begin();
			Visit visit = entityManager.find(Visit.class, transientObject.getId());
			visit = transientObject;
			entityManager.merge(visit);
			entityManager.getTransaction().commit();
		} catch (Exception e) {
			entityManager.getTransaction().rollback();
			LOG.info(e.getMessage());
			LOG.debug("DEBUG: ", e);
		}		
	}

	@Override
	public void delete(Visit transientObject) throws SQLException {
		try {
			entityManager.getTransaction().begin();
			entityManager.remove(transientObject);
			entityManager.getTransaction().commit();
		} catch (Exception e) {
			entityManager.getTransaction().rollback();
			LOG.info(e.getMessage());
			LOG.debug("DEBUG: ", e);
		}		
	}
	
	public List<Visit> getVisitToArchive() {
		List<Visit> listVisit = new ArrayList<>();
		try {
			entityManager.getTransaction().begin();
			Query query = entityManager.createQuery("select k from Visit k where k.isArchived = false and k.isActive = false");
			listVisit = (ArrayList<Visit>) query.getResultList();
			entityManager.getTransaction().commit();
		} catch (Exception e) {
			entityManager.getTransaction().rollback();
			e.printStackTrace();
			LOG.info(e.getMessage());
			LOG.debug("DEBUG: ", e);
		}
		
		return listVisit;
	}

	public EntityManagerFactoryService getEntityManagerFactory() {
		return entityManagerFactory;
	}

	public void setEntityManagerFactory(EntityManagerFactoryService entityManagerFactory) {
		this.entityManagerFactory = entityManagerFactory;
	}
	
}
